package com.jsh.erp.service.accountHead;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.jsh.erp.constants.BusinessConstants;
import com.jsh.erp.constants.ExceptionConstants;
import com.jsh.erp.datasource.entities.*;
import com.jsh.erp.datasource.mappers.*;
import com.jsh.erp.datasource.vo.*;
import com.jsh.erp.exception.BusinessRunTimeException;
import com.jsh.erp.exception.JshException;
import com.jsh.erp.service.WorkflowConfig.WorkflowConfigService;
import com.jsh.erp.service.accountItem.AccountItemService;
import com.jsh.erp.service.attachment.AttachmentService;
import com.jsh.erp.service.depotHead.DepotHeadService;
import com.jsh.erp.service.log.LogService;
import com.jsh.erp.service.orgaUserRel.OrgaUserRelService;
import com.jsh.erp.service.supplier.SupplierService;
import com.jsh.erp.service.systemConfig.SystemConfigService;
import com.jsh.erp.service.user.UserService;
import com.jsh.erp.service.userBusiness.UserBusinessService;
import com.jsh.erp.utils.IdUtils;
import com.jsh.erp.utils.StringUtil;
import com.jsh.erp.utils.Tools;
import org.apache.ibatis.annotations.Param;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;

import static com.jsh.erp.utils.Tools.getCenternTime;

@Service
public class AccountHeadService {
    private Logger logger = LoggerFactory.getLogger(AccountHeadService.class);
    @Resource
    private AccountHeadMapper accountHeadMapper;
    @Resource
    private AccountHeadMapperEx accountHeadMapperEx;
    @Resource
    private OrgaUserRelService orgaUserRelService;
    @Resource
    private AccountItemService accountItemService;
    @Resource
    private UserService userService;
    @Resource
    private SupplierService supplierService;
    @Resource
    private LogService logService;
    @Resource

    private AccountItemMapperEx accountItemMapperEx;
    @Resource
    private UserBusinessService userBusinessService;
    @Resource
    private WorkflowConfigService workflowConfigService;
    @Resource
    private AttachmentService attachmentService;
    @Resource
    private AttachmentMapperEx attachmentMapperEx;
    @Resource
    private SystemConfigService systemConfigService;
    @Resource
    private WorkflowProcessDetailMapperEx workflowProcessDetailMapperEx;
    @Resource
    private WorkflowApproveDetailMapperEx workflowApproveDetailMapperEx;
    @Resource
    private DepotHeadService depotHeadService;
    @Resource
    private DepotHeadMapper depotHeadMapper;
    @Resource
    private SynchronizationTaskMapperEx synchronizationTaskMapperEx;

    public AccountHead getAccountHead(String id) throws Exception {
        AccountHead result=null;
        try{
            result=accountHeadMapper.selectByPrimaryKey(id);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }

    public List<AccountHead> getAccountHeadListByIds(String ids)throws Exception {
        List<String> idList = StringUtil.strToStringList(ids);
        List<AccountHead> list = new ArrayList<>();
        try{
            AccountHeadExample example = new AccountHeadExample();
            example.createCriteria().andIdIn(idList);
            list = accountHeadMapper.selectByExample(example);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return list;
    }

    public List<AccountHead> getAccountHead() throws Exception{
        AccountHeadExample example = new AccountHeadExample();
        List<AccountHead> list=null;
        try{
            list=accountHeadMapper.selectByExample(example);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return list;
    }

    public List<AccountHeadVo4ListEx> select(String type, String roleType, String billNo, String beginTime, String endTime,
                                             String organId, String creator, String handsPersonId, String accountId, String status,
                                             String remark, int offset, int rows) throws Exception{
        List<AccountHeadVo4ListEx> resList = new ArrayList<>();
        try{
            String [] creatorArray = getCreatorArray(roleType);
            beginTime = Tools.parseDayToTime(beginTime,BusinessConstants.DAY_FIRST_TIME);
            endTime = Tools.parseDayToTime(endTime,BusinessConstants.DAY_LAST_TIME);
            String[] statusArray = StringUtil.isNotEmpty(status) ? status.split(",") : null;
            List<AccountHeadVo4ListEx> list = accountHeadMapperEx.selectByConditionAccountHead(type, creatorArray, billNo,
                    beginTime, endTime, organId, creator, handsPersonId, accountId, statusArray, remark, offset, rows);
            if (null != list) {
                for (AccountHeadVo4ListEx ah : list) {
                    if(ah.getChangeAmount() != null) {
                        ah.setChangeAmount(ah.getChangeAmount().abs());
                    }
                    if(ah.getTotalPrice() != null) {
                        ah.setTotalPrice(ah.getTotalPrice().abs());
                    }
                    if(ah.getBillTime() !=null) {
                        ah.setBillTimeStr(getCenternTime(ah.getBillTime()));
                    }
                    Integer approveProcess = workflowApproveDetailMapperEx.getBillProcessByNumber(ah.getBillNo());
                    if (approveProcess != null){
                        ah.setProcess(approveProcess);
                    }else {
                        ah.setProcess(workflowProcessDetailMapperEx.getBillProcessByNumber(ah.getBillNo()));
                    }
                    resList.add(ah);
                }
            }
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return resList;
    }

    public Long countAccountHead(String type, String roleType, String billNo, String beginTime, String endTime,
                                 String organId, String creator, String handsPersonId, String accountId, String status,
                                 String remark) throws Exception{
        Long result=null;
        try{
            String [] creatorArray = getCreatorArray(roleType);
            beginTime = Tools.parseDayToTime(beginTime,BusinessConstants.DAY_FIRST_TIME);
            endTime = Tools.parseDayToTime(endTime,BusinessConstants.DAY_LAST_TIME);
            result = accountHeadMapperEx.countsByAccountHead(type, creatorArray, billNo,
                    beginTime, endTime, organId, creator, handsPersonId, accountId, status, remark);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }

    /**
     * 根据角色类型获取操作员数组
     * @param roleType
     * @return
     * @throws Exception
     */
    private String[] getCreatorArray(String roleType) throws Exception {
        String creator = "";
        User user = userService.getCurrentUser();
        if(BusinessConstants.ROLE_TYPE_PRIVATE.equals(roleType)) {
            creator = user.getId().toString();
        } else if(BusinessConstants.ROLE_TYPE_THIS_ORG.equals(roleType)) {
            creator = orgaUserRelService.getUserIdListByUserId(user.getId());
        }
        String [] creatorArray=null;
        if(StringUtil.isNotEmpty(creator)){
            creatorArray = creator.split(",");
        }
        return creatorArray;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int insertAccountHead(JSONObject obj, HttpServletRequest request) throws Exception{
        AccountHead accountHead = JSONObject.parseObject(obj.toJSONString(), AccountHead.class);
        int result=0;
        try{
//            User userInfo=userService.getCurrentUser();
//            accountHead.setCreator(userInfo==null?null:userInfo.getId());
            accountHead.setUploadFlag("0");
            result = accountHeadMapper.insertSelective(accountHead);
            logService.insertLog("财务",
                    new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_ADD).append(accountHead.getBillNo()).toString(), request);
        }catch(Exception e){
            JshException.writeFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int updateAccountHead(JSONObject obj, HttpServletRequest request)throws Exception {
        AccountHead accountHead = JSONObject.parseObject(obj.toJSONString(), AccountHead.class);
        int result=0;
        try{
            accountHead.setUploadFlag("0");
            result = accountHeadMapper.updateByPrimaryKeySelective(accountHead);
            logService.insertLog("财务",
                    new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(accountHead.getBillNo()).toString(), request);
        }catch(Exception e){
            JshException.writeFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int deleteAccountHead(String id, HttpServletRequest request)throws Exception {
        return batchDeleteAccountHeadByIds(id.toString());
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int batchDeleteAccountHead(String ids, HttpServletRequest request)throws Exception {
        return batchDeleteAccountHeadByIds(ids);
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int batchDeleteAccountHeadByIds(String ids)throws Exception {
        StringBuffer sb = new StringBuffer();
        sb.append(BusinessConstants.LOG_OPERATION_TYPE_DELETE);
        List<AccountHead> list = getAccountHeadListByIds(ids);
        for(AccountHead accountHead: list){
            sb.append("[").append(accountHead.getBillNo()).append("]");
            if("1".equals(accountHead.getStatus())) {
                throw new BusinessRunTimeException(ExceptionConstants.ACCOUNT_HEAD_UN_AUDIT_DELETE_FAILED_CODE,
                        String.format("zh".equals(systemConfigService.getLanCode()) ? ExceptionConstants.ACCOUNT_HEAD_UN_AUDIT_DELETE_FAILED_MSG : ExceptionConstants.ACCOUNT_HEAD_UN_AUDIT_DELETE_FAILED_MSG_US));
            }
            //删除待审批任务
            workflowProcessDetailMapperEx.batchDeleteByBillId(new String[]{accountHead.getBillNo()});
            if ("返利收款".equals(accountHead.getType())){
                depotHeadService.updateDepotHeadByRebate(accountHead,"delete");
            }
            //给结算的单据修改状态
            if ("收款".equals(accountHead.getType())) {
                List<AccountItemVo4List> detailList = accountItemMapperEx.getDetailList(accountHead.getId());
                if (detailList !=null && detailList.size()>0){
                    for (AccountItemVo4List accountItemVo4List: detailList){
                        String billId = accountItemVo4List.getBillId();
                       depotHeadService.updateCustom12ByBillId(billId);
                    }
                }
            }
        }
        User userInfo=userService.getCurrentUser();
        String [] idArray=ids.split(",");
        //删除主表
        accountItemMapperEx.batchDeleteAccountItemByHeadIds(new Date(),userInfo==null?null:userInfo.getId(),idArray);
        //删除子表
        accountHeadMapperEx.batchDeleteAccountHeadByIds(new Date(),userInfo==null?null:userInfo.getId(),idArray);
        //删除附件
        attachmentMapperEx.batchDeleteAttachmentByHeadId(new Date(),userInfo==null?null:userInfo.getId(),idArray);

        logService.insertLog("财务", sb.toString(),StringUtil.getRequest());
        return 1;
    }

     public int checkIsNameExist(String id, String name) throws Exception{
        AccountHeadExample example = new AccountHeadExample();
        example.createCriteria().andIdNotEqualTo(id).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        List<AccountHead> list = null;
        try{
            list = accountHeadMapper.selectByExample(example);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return list==null?0:list.size();
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public int batchSetStatus(String status, String accountHeadIds)throws Exception {
        int result = 0;
        try{
            List<String> ahIds = new ArrayList<>();
            List<String> ids = StringUtil.strToStringList(accountHeadIds);
            for(String id: ids) {
                AccountHead accountHead = getAccountHead(id);
                if("0".equals(status)){
                    if("1".equals(accountHead.getStatus())) {
                        Supplier supplier = supplierService.getSupplier(accountHead.getOrganId());
                        if("预收款".equals(accountHead.getType()) || "预付款".equals(accountHead.getType())){
                            supplierService.updateAdvanceIn(accountHead.getOrganId(),BigDecimal.ZERO.subtract(accountHead.getChangeAmount().abs()));
                        }
//                        if ("返利收款".equals(accountHead.getType())){
//                            depotHeadService.updateDepotHeadByRebate(accountHead,1);
//                        }
                        if (accountHead.getCustom10() != null){
                            if(accountHead.getCustom10().compareTo(BigDecimal.ZERO) != 0){
                                supplierService.subtractAdvanceIn(accountHead.getOrganId(),BigDecimal.ZERO.subtract(accountHead.getCustom10().abs()));
                            }
                        }
                        ahIds.add(id);
                    }
                } else if("1".equals(status)){
                    if("0".equals(accountHead.getStatus())) {
                        Supplier supplier = supplierService.getSupplier(accountHead.getOrganId());
                        if ("预收款".equals(accountHead.getType()) || "预付款".equals(accountHead.getType())) {
                            if (supplier != null) {
                                supplierService.updateAdvanceIn(accountHead.getOrganId(), accountHead.getChangeAmount().abs());
                            }
                        }
//                        if ("返利收款".equals(accountHead.getType())){
//                            depotHeadService.updateDepotHeadByRebate(accountHead.getNumber(),2);
//                        }
                        if (accountHead.getCustom10() != null){
                            if(accountHead.getCustom10().compareTo(BigDecimal.ZERO) != 0){
                                supplierService.subtractAdvanceIn(accountHead.getOrganId(),accountHead.getCustom10().abs());
                            }
                        }
                        ahIds.add(id);
                    }
                }
            }
            if(ahIds.size()>0) {
                AccountHead accountHead = new AccountHead();
                accountHead.setStatus(status);
                accountHead.setUploadFlag("0");
                AccountHeadExample example = new AccountHeadExample();
                example.createCriteria().andIdIn(ahIds);
                result = accountHeadMapper.updateByExampleSelective(accountHead, example);
            } else {
                return 1;
            }
        }catch(Exception e){
            JshException.writeFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public void addAccountHeadAndDetail(String beanJson, String rows,String attachment, HttpServletRequest request,boolean passDirect,
                                        String functionId) throws Exception {
        AccountHead accountHead = JSONObject.parseObject(beanJson, AccountHead.class);
        if ("预付款".equals(accountHead.getType())||"预收款".equals(accountHead.getType())||"付款".equals(accountHead.getType())
                ||"预付款单".equals(accountHead.getType())||"直发付款".equals(accountHead.getType())||"直发预付款".equals(accountHead.getType())){
            User userInfo=userService.getCurrentUser();
            if (!"0".equals(userInfo.getTenantId()) && StringUtil.isNotEmpty(userInfo.getTenantId())){
                throw new BusinessRunTimeException(ExceptionConstants.DATA_WRITE_FAIL_CODE,
                        "zh".equals(systemConfigService.getLanCode()) ? "请用管理员账号新增": "Please use the administrator account to add");
            }
        }
        accountHead.setId(IdUtils.getUUID());
        accountHead.setUploadFlag("0");
//        accountHead.setCreator(userInfo==null?null:userInfo.getId());
        if(StringUtil.isEmpty(accountHead.getStatus())) {
            accountHead.setStatus(BusinessConstants.BILLS_STATUS_UN_AUDIT);
        }
        accountHeadMapper.insertSelective(accountHead);
        //根据单据编号查询单据id
        AccountHeadExample dhExample = new AccountHeadExample();
        dhExample.createCriteria().andBillNoEqualTo(accountHead.getBillNo()).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        List<AccountHead> list = accountHeadMapper.selectByExample(dhExample);
        if(list!=null) {
            String headId = list.get(0).getId();
            String type = list.get(0).getType();
            if(!"预收款".equals(accountHead.getType()) && !"预付款".equals(accountHead.getType())&&
                    !"返利收款".equals(accountHead.getType()) &&!"支出".equals(accountHead.getType())&&!"收入".equals(accountHead.getType()) ){
                /**处理单据子表信息*/
                accountItemService.saveDetials(rows, headId, type, request,"add");
            }
            if ("返利收款".equals(accountHead.getType())){
                depotHeadService.updateDepotHeadByRebate(accountHead,"add");
            }
            /**处理文件**/
            attachmentService.saveAttachment(attachment,headId,request);
        }
//        if("预收款单".equals(accountHead.getType())){
//            supplierService.updateAdvanceIn(accountHead.getOrganId(), accountHead.getTotalPrice());
//        }
        logService.insertLog("财务单据",
                new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_ADD).append(accountHead.getBillNo()).toString(), request);
        if(passDirect){
            String keyId = userBusinessService.checkValueExist("ConfigRoleFunctions", "[" + functionId + "]",request);
            if (StringUtils.isNotEmpty(keyId)){
                workflowConfigService.addProcessDetailWithAccount(keyId,accountHead);
            }else {
                accountHead.setStatus(BusinessConstants.BILLS_STATUS_AUDIT);
                accountHead.setUploadFlag("0");
                accountHeadMapper.updateByPrimaryKeySelective(accountHead);
                if("预收款".equals(accountHead.getType()) || "预付款".equals(accountHead.getType())){
                    supplierService.updateAdvanceIn(accountHead.getOrganId(),accountHead.getChangeAmount().abs());
                }
//                if ("返利收款".equals(accountHead.getType())){
//                    depotHeadService.updateDepotHeadByRebate(accountHead,"update");
//                }
                if (accountHead.getCustom10() != null ){
                    if(accountHead.getCustom10().compareTo(BigDecimal.ZERO) != 0){
                        supplierService.subtractAdvanceIn(accountHead.getOrganId(),accountHead.getCustom10().abs());
                    }
                }
            }
        }
    }

    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
    public void updateAccountHeadAndDetail(String beanJson, String rows,String attachment, HttpServletRequest request,boolean passDirect,
                                           String functionId) throws Exception {
        AccountHead accountHead = JSONObject.parseObject(beanJson, AccountHead.class);
        //获取之前的金额数据
        BigDecimal preTotalPrice = getAccountHead(accountHead.getId()).getTotalPrice().abs();
        accountHead.setUploadFlag("0");
        accountHeadMapper.updateByPrimaryKeySelective(accountHead);
        //根据单据编号查询单据id
        AccountHeadExample dhExample = new AccountHeadExample();
        dhExample.createCriteria().andBillNoEqualTo(accountHead.getBillNo()).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
        List<AccountHead> list = accountHeadMapper.selectByExample(dhExample);
        if(list!=null) {
            String headId = list.get(0).getId();
            String type = list.get(0).getType();
            if(!"预收款".equals(accountHead.getType()) && !"预付款".equals(accountHead.getType())&& !"返利收款".equals(accountHead.getType())
                    &&!"支出".equals(accountHead.getType())&&!"收入".equals(accountHead.getType())){
                /**处理单据子表信息*/
                accountItemService.saveDetials(rows, headId, type, request,"update");
            }
            if ("返利收款".equals(accountHead.getType())){
                depotHeadService.updateDepotHeadByRebate(accountHead,"update");
            }
            /**处理文件**/
            attachmentService.saveAttachment(attachment,headId,request);
        }
//        if("预收款单".equals(accountHead.getType())){
//            supplierService.updateAdvanceIn(accountHead.getOrganId(), accountHead.getTotalPrice().subtract(preTotalPrice));
//        }
        logService.insertLog("财务单据",
                new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(accountHead.getBillNo()).toString(), request);
        if(passDirect){
            String keyId = userBusinessService.checkValueExist("ConfigRoleFunctions", "[" + functionId + "]",request);
            if (StringUtils.isNotEmpty(keyId)){
                workflowConfigService.addProcessDetailWithAccount(keyId,accountHead);
            }else {
                accountHead.setStatus(BusinessConstants.BILLS_STATUS_AUDIT);
                accountHead.setUploadFlag("0");
                accountHeadMapper.updateByPrimaryKeySelective(accountHead);
                if("预收款".equals(accountHead.getType()) || "预付款".equals(accountHead.getType())){
                    supplierService.updateAdvanceIn(accountHead.getOrganId(),accountHead.getChangeAmount().abs());
                }
//                if ("返利收款".equals(accountHead.getType())){
//                    depotHeadService.updateDepotHeadByRebate(accountHead.getNumber(),1);
//                }
                if (accountHead.getCustom10() != null ){
                    if(accountHead.getCustom10().compareTo(BigDecimal.ZERO) != 0){
                        supplierService.subtractAdvanceIn(accountHead.getOrganId(),accountHead.getCustom10().abs());
                    }
                }
            }
        }
    }

    public BigDecimal findAllMoney(String supplierId, String type, String mode, String endTime) {
        String modeName = "";
        if (mode.equals("实际")) {
            modeName = "change_amount";
        } else if (mode.equals("合计")) {
            modeName = "total_price";
        }
        BigDecimal result = null;
        try{
            result = accountHeadMapperEx.findAllMoney(supplierId, type, modeName, endTime);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }

    /**
     * 统计总金额
     * @param getS
     * @param type
     * @param mode 合计或者金额
     * @param endTime
     * @return
     */
    public BigDecimal allMoney(String getS, String type, String mode, String endTime) {
        BigDecimal allMoney = BigDecimal.ZERO;
        try {
            BigDecimal sum = findAllMoney(getS, type, mode, endTime);
            if(sum != null) {
                allMoney = sum;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //返回正数，如果负数也转为正数
        if ((allMoney.compareTo(BigDecimal.ZERO))==-1) {
            allMoney = allMoney.abs();
        }
        return allMoney;
    }

    /**
     * 查询往来单位的累计应收和累计应付，只计入收款或付款
     * @param supplierId
     * @param endTime
     * @param supType
     * @return
     */
    public BigDecimal findTotalPay(String supplierId, String endTime, String supType) {
        BigDecimal sum = BigDecimal.ZERO;
//        String getS = supplierId.toString();
        if (("客户").equals(supType)) { //客户
            sum = allMoney(supplierId, "收款,预收款单", "合计",endTime);
        } else if (("供应商").equals(supType)) { //供应商
            sum = allMoney(supplierId, "付款,预付款单", "合计",endTime);
        }
        return sum;
    }

    public List<AccountHeadVo4ListEx> getDetailByNumber(String billNo)throws Exception {
        List<AccountHeadVo4ListEx> resList = new ArrayList<AccountHeadVo4ListEx>();
        List<AccountHeadVo4ListEx> list = null;
        try{
            list = accountHeadMapperEx.getDetailByNumber(billNo);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        if (null != list) {
            for (AccountHeadVo4ListEx ah : list) {
                if(ah.getChangeAmount() != null) {
                    ah.setChangeAmount(ah.getChangeAmount().abs());
                }
                if(ah.getTotalPrice() != null) {
                    ah.setTotalPrice(ah.getTotalPrice().abs());
                }
                ah.setBillTimeStr(getCenternTime(ah.getBillTime()));
                resList.add(ah);
            }
        }
        return resList;
    }

    public List<AccountHead> getFinancialBillNoByBillId(String billId) {
        return accountHeadMapperEx.getFinancialBillNoByBillId(billId);
    }

    public List<AccountHeadVo> getListByOrganId(String organId,String beginTime,String endTime,String number,Integer pageNum,Integer pageSize) {
        return accountHeadMapperEx.getListByOrganId(organId,beginTime,endTime,number,pageNum, pageSize);
    }
//    public List<AccountHeadVo> getAllBillByOrganId(String organId,String beginTime,String endTime,String number,Integer pageNum,Integer pageSize) {
//        return accountHeadMapperEx.getAllBillByOrganId(organId,beginTime,endTime,number,pageNum, pageSize);
//    }
//    public List<AccountHeadVo> getAllBillByOrganIdCount(String organId,String beginTime,String endTime,String number) {
//        return accountHeadMapperEx.getAllBillByOrganIdCount(organId,beginTime,endTime,number);
//    }

    public List<AccountHeadVo> getAllBillByOrganId(String organId,String beginTime,String endTime,String number, Integer offset, Integer rows) throws Exception{
        List<AccountHeadVo> list=null;
        List<AccountHeadVo> headVoList=new ArrayList<>();
        try{
            beginTime = Tools.parseDayToTime(beginTime,BusinessConstants.DAY_FIRST_TIME);
            endTime = Tools.parseDayToTime(endTime,BusinessConstants.DAY_LAST_TIME);
            list = accountHeadMapperEx.getAllBillByOrganId(organId,beginTime,endTime,number, offset, rows);
            if (null != list) {
                for (AccountHeadVo aEx : list) {
                    String type = aEx.getType().replace("其它", "");
                    aEx.setType(type);
                    String timeStr = aEx.getBillTime().toString();
                    Supplier supplier = supplierService.getSupplier(organId);
                    BigDecimal balance = supplierService.getSupplierSum(supplier)
                            .add(supplierService.getSupplierSumByHead(organId, timeStr,supplier.getType()))
                            .add(supplierService.getSupplierSumByDepotHead(organId, timeStr,supplier.getType()));
                    aEx.setBalance(balance);
                    headVoList.add(aEx);
//                    aEx.setBalance(accountHeadMapperEx.getBalance(organId,aEx.getBillTime()).add(aEx.getTotalPrice()));
                }
            }
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return list;
    }

    public int getAllBillByOrganIdCount(String organId,String beginTime,String endTime,String number) throws Exception{
        int result=0;
        try{
            beginTime = Tools.parseDayToTime(beginTime,BusinessConstants.DAY_FIRST_TIME);
            endTime = Tools.parseDayToTime(endTime,BusinessConstants.DAY_LAST_TIME);
            result = accountHeadMapperEx.getAllBillByOrganIdCount(organId,beginTime,endTime,number);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }

    public List<CheckVo> checkAlert(Integer pageNum, Integer pageSize) {
        return accountHeadMapperEx.checkAlert(pageNum,pageSize);
    }


    public List<AccountHeadWithTransportReport> getAllBillByType(String organId,String beginTime,String endTime,String accountId, Integer offset, Integer rows,String status) throws Exception{
        List<AccountHeadWithTransportReport> list=null;
        List<AccountHeadWithTransportReport> headVoList=new ArrayList<>();
        try{
            beginTime = Tools.parseDayToTime(beginTime,BusinessConstants.DAY_FIRST_TIME);
            endTime = Tools.parseDayToTime(endTime,BusinessConstants.DAY_LAST_TIME);
            list = accountHeadMapperEx.getAllBillByType(organId,beginTime,endTime,accountId, offset, rows,status);
            if (null != list) {
                for (AccountHeadWithTransportReport aEx : list) {
                    aEx.setBillTimeStr(getCenternTime(aEx.getBillTime()));
                    headVoList.add(aEx);
                }
            }
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return list;
    }

    public int getAllBillByTypeCount(String organId,String beginTime,String endTime,String accountId,String status) throws Exception{
        int result=0;
        try{
            beginTime = Tools.parseDayToTime(beginTime,BusinessConstants.DAY_FIRST_TIME);
            endTime = Tools.parseDayToTime(endTime,BusinessConstants.DAY_LAST_TIME);
            result = accountHeadMapperEx.getAllBillByTypeCount(organId,beginTime,endTime,accountId,status);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }

    public List<AccountItemWithTransport> getDetailByTransportNo(String custom3,String type)throws Exception {
        List<AccountItemWithTransport> resList = new ArrayList<AccountItemWithTransport>();
        List<AccountItemWithTransport> list = null;
        try{
            list = accountHeadMapperEx.getDetailByTransportNo(custom3,type);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        if (null != list) {
            for (AccountItemWithTransport ah : list) {
                ah.setBillTimeStr(getCenternTime(ah.getBillTime()));
                resList.add(ah);
            }
        }
        return resList;
    }

    public List<AccountHeadWithInvoice> getInvoiceAmountByType(String organId, String beginTime, String endTime,
                                                               String accountId, Integer offset, Integer rows, String status,
                                                               String billStatus) throws Exception{
        List<AccountHeadWithInvoice> list=null;
        List<AccountHeadWithInvoice> headVoList=new ArrayList<>();
        try{
            beginTime = Tools.parseDayToTime(beginTime,BusinessConstants.DAY_FIRST_TIME);
            endTime = Tools.parseDayToTime(endTime,BusinessConstants.DAY_LAST_TIME);
            list = accountHeadMapperEx.getInvoiceAmountByType(organId,beginTime,endTime,accountId, offset, rows,status,billStatus);
            if (null != list) {
                for (AccountHeadWithInvoice aEx : list) {
                    aEx.setBillTimeStr(getCenternTime(aEx.getBillTime()));
                    headVoList.add(aEx);
                }
            }
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return list;
    }

    public int getInvoiceAmountByTypeCount(String organId,String beginTime,String endTime,String accountId,String status,String billStatus) throws Exception{
        int result=0;
        try{
            beginTime = Tools.parseDayToTime(beginTime,BusinessConstants.DAY_FIRST_TIME);
            endTime = Tools.parseDayToTime(endTime,BusinessConstants.DAY_LAST_TIME);
            result = accountHeadMapperEx.getInvoiceAmountByTypeCount(organId,beginTime,endTime,accountId,status,billStatus);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return result;
    }

    public AccountHeadWithDeposit getDepositByNumber(String number,String payStatus)throws Exception {
        AccountHeadWithDeposit total= null;
        try{
            total = accountHeadMapperEx.getDepositAndBillNoByNumber(number,payStatus);
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return total;
    }
    public List<AccountHeadWithDaily> getStatementByDaily()throws Exception {
        List<AccountHeadWithDaily> total= null;
        try{
            total = accountHeadMapperEx.getStatementByDaily();
        }catch(Exception e){
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return total;
    }

    public Boolean selectSuperStatus(AccountHead accountHead) {
        Integer count = 0;
        if("收款".equals(accountHead.getType())||
                "直发收款".equals(accountHead.getType())||
                "预收款".equals(accountHead.getType())||
                "预收款单".equals(accountHead.getType())||
                "直发预收款".equals(accountHead.getType())){
            count = accountHeadMapperEx.selectCheckSuperStatus(accountHead.getId());
        }else if("直发运费".equals(accountHead.getType()) || "运费".equals(accountHead.getType())){
            count = accountHeadMapperEx.selectFreightSuperStatus(accountHead.getId());
        }else {
            count = accountHeadMapperEx.selectSuperStatus(accountHead.getId());
        }
        if( "预收款单".equals(accountHead.getType())||
                "直发预收款".equals(accountHead.getType())){
            count = accountHeadMapperEx.selectCheckBillNoStatus(accountHead.getBillNo());
        }
        if (count>0){
            return false;
        }else {
            return true;
        }
    }


    public BigDecimal getAccountByRebate(String number,String id){
        BigDecimal amount = BigDecimal.ZERO;
        AccountHeadExample example = new AccountHeadExample();
        example.createCriteria().andNumberEqualTo(number).andTypeEqualTo("返利收款")
                .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED)
                .andIdNotEqualTo(id);
        List<AccountHead> accountHeads = accountHeadMapper.selectByExample(example);
        if (accountHeads != null && accountHeads.size()>0){
            for (AccountHead accountHead:accountHeads){
                amount=amount.add(accountHead.getChangeAmount());
            }
        }
        return amount;
    }

    public BigDecimal getAdvanceInBySupplierId(String id,String type){
        BigDecimal amount = BigDecimal.ZERO;
        List<AccountHead> accountHeads = synchronizationTaskMapperEx.getAdvanceInBySupplierId(id,type);
        if (accountHeads != null && accountHeads.size()>0){
            for (AccountHead accountHead:accountHeads){
                amount=amount.add(accountHead.getChangeAmount());
            }
        }
        return amount;
    }
    public BigDecimal getPayAdvanceInBySupplierId(String id,String type){
        BigDecimal amount = BigDecimal.ZERO;
        List<AccountHead> accountHeads = synchronizationTaskMapperEx.getPayAdvanceInBySupplierId(id,type);
        if (accountHeads != null && accountHeads.size()>0){
            for (AccountHead accountHead:accountHeads){
                amount=amount.add(accountHead.getCustom10());
            }
        }
        return amount;
    }
    public BigDecimal inOrOutMoney(String month,String type){
        BigDecimal amount = BigDecimal.ZERO;
        try {
            String beginTime = Tools.firstDayOfMonth(month) + BusinessConstants.DAY_FIRST_TIME;
            String endTime = Tools.lastDayOfMonth(month) + BusinessConstants.DAY_LAST_TIME;
            amount = accountHeadMapperEx.inOrOutMoney(beginTime,endTime,type);
        } catch (Exception e) {
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return amount;
    }

    public Map<String, Object> getDepositChangeByNumber(DepotHead dh,String payStatus){
        Map<String, Object> amount =new HashMap<>();
        try {
            amount = accountHeadMapperEx.getDepositChangeByNumber(dh.getNumber(), payStatus);
        } catch (Exception e) {
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return amount;
    }

    public String  getDepositByLinkNumber(DepotHead dh,String payStatus){
        String amount =null;
        try {
            amount = accountHeadMapperEx.getDepositByLinkNumber(dh.getNumber(), payStatus);
        } catch (Exception e) {
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return amount;
    }

   public String  getDepositByLinkNumberWithCustom9(DepotHead dh,String payStatus){
        String amount =null;
        try {
            amount = accountHeadMapperEx.getDepositByLinkNumberWithCustom9(dh.getNumber(), payStatus);
        } catch (Exception e) {
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return amount;
    }

    public String  getDepositByHeadLinkNumber(DepotHead dh,String payStatus,String changeStatus){
        String amount =null;
        try {
            amount = accountHeadMapperEx.getDepositByHeadLinkNumber(dh.getNumber(), payStatus,changeStatus);
        } catch (Exception e) {
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return amount;
    }

    public List<String>  getCustom2ByBillId(DepotHead dh,String payStatus){
        List<String> amount =null;
        try {
            amount = accountHeadMapperEx.getCustom2ByBillId(dh.getId(), payStatus);
        } catch (Exception e) {
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return amount;
    }
    public  String getDepositByCustom2(List<String> strList){
        String amount =null;
        try {
            amount = accountHeadMapperEx.getDepositByCustom2(strList);
        } catch (Exception e) {
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return amount;
    }
    public  String getPaymentByBillId(DepotHead dh,String payStatus){
        String amount =null;
        try {
            amount = accountHeadMapperEx.getPaymentByBillId(dh.getId(), payStatus);
        } catch (Exception e) {
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return amount;
    }
    public  String getPaymentByBillId(List<String> idList,String payStatus){
        String amount =null;
        try {
            amount = accountHeadMapperEx.getPaymentByBillIdList(idList, payStatus);
        } catch (Exception e) {
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return amount;
    }
    public  PaymentVo getPaymentByBillIdNotAccountName(String billId,String payStatus){
        PaymentVo amount =null;
        try {
            amount = accountHeadMapperEx.getPaymentByBillIdNotAccountName(billId,payStatus);
        } catch (Exception e) {
            JshException.readFail(logger, e, systemConfigService.getLanCode());
        }
        return amount;
    }
}
